package com.huang.security.handler;

import com.alibaba.fastjson.JSONObject;
import com.huang.enums.UserCodeEnum;
import com.huang.resp.CommonResult;
import lombok.extern.log4j.Log4j2;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

/**
 * 登录失败处理
 *
 * @author han
 * @since 2022-01-16 15:32:34
 */
@Log4j2
@Component
public class DefaultAuthenticationFailHandler implements ServerAuthenticationFailureHandler {

    @Override
    public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) {
        log.info("登录失败时，会出现的提示！");
        return Mono.defer(() -> Mono.just(webFilterExchange.getExchange().getResponse()).flatMap(response -> {
            DataBufferFactory dataBufferFactory = response.bufferFactory();
            CommonResult commonResult = CommonResult.error(UserCodeEnum.LOGIN_PASSWORD_ERROR);
            if (exception instanceof UsernameNotFoundException) {
                // 账号不存在
                commonResult = CommonResult.error(UserCodeEnum.ACCOUNT_NOT_EXIST);
            } else if (exception instanceof BadCredentialsException) {
                // 用户名或密码错误
                commonResult = CommonResult.error(UserCodeEnum.LOGIN_PASSWORD_ERROR);
            } else if (exception instanceof AccountExpiredException) {
                // 账号已过期
                commonResult = CommonResult.error(UserCodeEnum.ACCOUNT_EXPIRED);
            } else if (exception instanceof LockedException) {
                 // 账号已被锁定
                commonResult = CommonResult.error(UserCodeEnum.ACCOUNT_LOCKED);
            } else if (exception instanceof CredentialsExpiredException) {
                // 用户凭证已失效
                commonResult = CommonResult.error(UserCodeEnum.ACCOUNT_CREDENTIAL_EXPIRED);
            } else if (exception instanceof DisabledException) {
                // 账号已被禁用
                commonResult = CommonResult.error(UserCodeEnum.ACCOUNT_DISABLE);
            }
            DataBuffer dataBuffer = dataBufferFactory.wrap(JSONObject.toJSONString(commonResult).getBytes());
            return response.writeWith(Mono.just(dataBuffer));
        }));
    }
}
